package com.wzl.customview.watchface;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.wzl.myviewgroup.R;
import com.wzl.myviewgroup.utils.SizeUtils;

import java.util.Calendar;
import java.util.TimeZone;

public class WatchFaceView extends View {


    private int mSecondColor;
    private int mMinColor;
    private int mHourColor;
    private int mScaleColor;
    private int mBgResId;
    private boolean isScaleShow;
    private Paint mPpaint;
    private Paint mSecondPaint;
    private Paint mMinPaint;
    private Paint mHourPaint;
    private Paint mScalePaint;
    private Bitmap mBackgroudImage=null;
    private Rect mSrcRect;
    private Rect mDesRect;
    private int mWidth;
    private int mHeight;
    private Calendar mCalendar;

    public WatchFaceView(Context context) {
        this(context, null);
    }

    public WatchFaceView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WatchFaceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性
        initAttrs(context, attrs);
        //创建画笔
        initPaint();
        //创建日历实例
        mCalendar = Calendar.getInstance();
        //设置时区
        mCalendar.setTimeZone(TimeZone.getDefault());


    }

    private void initRect() {
        if (mBackgroudImage==null) {
            return;
        }
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        //初始化源Rect，用于设置图片
        mSrcRect = new Rect();
        //设置目标Rect，用于设置图片显示区域
        mSrcRect.set(0, 0, mBackgroudImage.getWidth(), mBackgroudImage.getHeight());

        mDesRect = new Rect(0, 0, mWidth, mHeight);

    }

    private void initPaint() {
        mPpaint = new Paint();
        //设置画笔颜色
        mPpaint.setColor(Color.parseColor("#ffffff"));
        //设置画笔宽度
        mPpaint.setStrokeWidth(10);
        //抗锯齿
        mPpaint.setAntiAlias(true);
        //设置画笔样式
        mPpaint.setStyle(Paint.Style.STROKE);
        //设置画笔模式
        mPpaint.setStrokeJoin(Paint.Join.ROUND);
        //圆弧
        mPpaint.setStrokeCap(Paint.Cap.ROUND);

        Paint pPaint = new Paint();
        pPaint.setStyle(Paint.Style.STROKE);
        pPaint.setStrokeWidth(2f);
        pPaint.setAntiAlias(true);
        mPpaint.setStrokeCap(Paint.Cap.ROUND);

        //秒针
        mSecondPaint = new Paint(pPaint);
        mSecondPaint.setColor(mSecondColor);
        //分针
        mMinPaint = new Paint(pPaint);
        mMinPaint.setColor(mMinColor);
        mMinPaint.setStrokeWidth(3f);
        //时针
        mHourPaint = new Paint(pPaint);
        mHourPaint.setColor(mHourColor);
        mHourPaint.setStrokeWidth(4f);
        //刻度
        mScalePaint = new Paint(mMinPaint);
        mScalePaint.setColor(mScaleColor);

    }

    //获取自定义属性
    @NonNull
    private void initAttrs(Context context, @Nullable AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WatchFaceView);
        mSecondColor = a.getColor(R.styleable.WatchFaceView_secondColor, getResources().getColor(R.color.secondDefaultColor));
        mMinColor = a.getColor(R.styleable.WatchFaceView_minColor, getResources().getColor(R.color.minDefaultColor));
        mHourColor = a.getColor(R.styleable.WatchFaceView_hourColor, getResources().getColor(R.color.hourDefaultColor));
        mScaleColor = a.getColor(R.styleable.WatchFaceView_scaleColor, getResources().getColor(R.color.scaleDefaultColor));
        mBgResId = a.getResourceId(R.styleable.WatchFaceView_faceBackground, -1);
        isScaleShow = a.getBoolean(R.styleable.WatchFaceView_scaleShow, true);
        if (mBgResId != -1) {
//            mBackgroudImage = BitmapFactory.decodeResource(getResources(), mBgResId);
        }


        a.recycle();
    }

    //测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        Log.d("onMeasure", "width:" + widthSize + " height:" + heightSize);


        //减掉padding
        int widthTargetSize = widthSize - getPaddingLeft() - getPaddingRight();
        int heightTargetSize = heightSize - getPaddingTop() - getPaddingBottom();
        Log.d("onMeasure", "widthTargetSize:" + widthTargetSize + " heightTargetSize:" + heightTargetSize);
        //取宽高最小值
        int targetSize = Math.min(widthTargetSize, heightTargetSize);
        Log.d("onMeasure", "targetSize:" + targetSize);
        //正方形的宽高
        setMeasuredDimension(targetSize, targetSize);
        //初始化Rect
        initRect();
    }

    private boolean isUpdate = false;
    /*
    onAttachedToWindow() 是 View 类中的一个受保护（protected）方法，它在视图被附加到窗口时调用。
    这通常发生在视图被添加到一个窗口中，比如一个Activity的布局中，
    或者当Fragment的视图被附加到Activity的视图层次结构中时
    * */
    @Override
    protected void onAttachedToWindow() {
        //添加代码来执行当视图被附加到窗口时所需的操作
        super.onAttachedToWindow();//省略了这个调用，并且父类中有重要的逻辑在 onAttachedToWindow() 中，那么这些逻辑将不会被执行，可能会导致不可预见的行为或错误

        isUpdate = true;
        //开启线程,Handler的post方法
        post(new Runnable() {
            @Override
            public void run() {
                if (isUpdate) {
//                    invalidate();//调用View的invalidate()方法，通知系统重新绘制视图
                    postInvalidate();//调用View的postInvalidate()方法，通知系统重新绘制视图,线程安全
                    //每隔1000毫秒执行一次，Handler的postDelayed方法
                    postDelayed(this, 1000);
                }else {
                    removeCallbacks(this);//移除Handler的Runnable对象
                }
            }
        });
    }
    /*
    当视图从其窗口分离时，这个方法会被调用。
    这通常发生在视图被从Activity的布局中移除，或者Fragment的视图被从Activity的视图层次结构中分离时
    * */
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isUpdate = false;
    }

    /*
            θ为弧度
            "对边" 是在角 θ 的对面
            "邻边" 是在角 θ 的旁边
            "斜边" 是长的一边
            "对角线" 是斜边的一半
            "对角线斜边" 是对角线的长度
            "对角线斜边的一半" 是对角线的长度的一半

           正弦 （sine）,
           余弦 （cosine）
           正切 （tangent） （英语符号简写为 sin, cos 和 tan)
           余切 （cotangent）cot
           正割 （secant）sec
           余割 （cosecant） csc
             是 直角三角形 边长的比

           sin θ = 对边 / 斜边  4/5=0.8
           cos θ = 邻边 / 斜边 3/5=0.6
           tan θ = 对边 / 邻边
           cot(θ) = 邻边 / 对边
           sec(θ) = 斜边 / 邻边
           csc(θ) = 斜边 / 对边

            邻边*邻边+对边*对边=斜边*斜边

            Math.PI * 2: 这将计算圆的周长（即圆的直径乘以π），但由于圆的直径是2倍的半径，
            所以Math.PI * 2实际上是表示一个完整的圆的弧度（因为弧度与半径的长度成正比，
            而圆的周长正好是半径绕一圈的长度，所以一个完整的圆就是2π弧度）。

            1弧度=180/π度
            1度=π/180弧度
            弧度转换为角度公式：角度=弧度×（180÷π）
            角度转换为弧度公式：弧度=角度×(π÷180)
            0.5235987755982988

            * */
    //绘制
    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {

        //绘制背景
        canvas.drawColor(Color.parseColor("#000000"));
        //绘制刻度
        drawScale(canvas);

        //设置时间，获取当前时间
//        mCalendar.setTime(new Date());
        long currentTimeMillis = System.currentTimeMillis();
        mCalendar.setTimeInMillis(currentTimeMillis);
        
        //半径
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        int radius = (int)(width / 2f);
        int secondValue = mCalendar.get(Calendar.SECOND);
        if (secondValue==0) {
            //绘制秒针
            drawSecondLine(canvas, radius);
            //绘制分针
            drawMinLine(canvas, radius);
            //绘制时针
            drawHourLine(canvas, radius);
        }else{
            //绘制时针
            drawHourLine(canvas, radius);
            //绘制分针
            drawMinLine(canvas, radius);
            //绘制秒针
            drawSecondLine(canvas, radius);
        }
    }

    //绘制刻度
    private void drawScale(Canvas canvas) {
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        if (mBackgroudImage != null) {
            canvas.drawBitmap(mBackgroudImage, mSrcRect, mDesRect, mScalePaint);
        }else{
            //绘制时间刻度方法1
//            timeScale1(canvas, width, height);
            //绘制时间刻度方法2
            timeScale2(canvas, width);
            //绘制时间刻度中点
            canvas.drawCircle(width / 2, height / 2, SizeUtils.dip2px(5), mScalePaint);
        }
    }

    private void drawSecondLine(Canvas canvas, int radius) {
        canvas.save();
        int secondValue = mCalendar.get(Calendar.SECOND);
        //秒针长度
        int secondLength = (int)(radius * 0.9f);
        //秒针旋转的角度 = 秒钟数 * 360/60
        float secondRotate = secondValue * 360 / 60;
        //秒针旋转
        canvas.rotate(secondRotate, radius, radius);
        //绘制秒针
        canvas.drawLine(radius, radius -secondLength, radius, radius -SizeUtils.dip2px(6), mSecondPaint);
        canvas.restore();
    }

    private void drawHourLine(Canvas canvas, int radius) {
        canvas.save();
        int hourValue = mCalendar.get(Calendar.HOUR);
        int minValue = mCalendar.get(Calendar.MINUTE);
        //时针长度
        int hourLength = (int)(radius * 0.8f);
        //时针的旋转，以30度为1刻度，加分针旋转的角度，
        //时针旋转的角度 = 分钟数 * 30/60 ,一刻度为30度表示60分钟
        float hourOfSetRotate = minValue * 30 / 60;
        float hourRotate = hourValue * 30 + hourOfSetRotate;
        Log.d("WatchFaceView", "hourValue:" + hourValue);
        Log.d("WatchFaceView", "minValue:" + minValue);
        Log.d("WatchFaceView", "hourOfSetRotate:" + hourOfSetRotate);
        Log.d("WatchFaceView", "hourRotate:" + hourRotate);
        //时针旋转
        canvas.rotate(hourRotate, radius, radius);
        //绘制时针
        canvas.drawLine(radius, radius -hourLength, radius, radius -SizeUtils.dip2px(6), mHourPaint);
        canvas.restore();
    }

    private void drawMinLine(Canvas canvas, int radius) {
        canvas.save();
        int minValue = mCalendar.get(Calendar.MINUTE);
        //分针长度
        int minLength = (int)(radius * 0.85f);
        //分针旋转的角度 = 分钟数 * 360/60
        float minRotate = minValue * 360 / 60;
        //分针旋转
        canvas.rotate(minRotate, radius, radius);
        //绘制分针
        canvas.drawLine(radius, radius -minLength, radius, radius -SizeUtils.dip2px(6), mMinPaint);
        canvas.restore();
    }

    //绘制时间刻度方法2
    private void timeScale2(Canvas canvas, int width) {
        //半径
        int radius = (int)(width / 2f);
        //外圈半
        int outerRadius = (int)(width / 2f * 0.9f);
        //内环半径
        int innerRadius = (int)(width /2 * 0.85f);
        canvas.save();
        for (int i = 0; i < 12; i++) {
            canvas.drawLine(radius,radius-outerRadius,radius,radius-innerRadius,mScalePaint);
            //旋转
            canvas.rotate(30,radius,radius);
//                canvas.drawLine(radius,radius-radius,radius,radius-innerRadius,mScalePaint);
        }
        canvas.restore();
    }

    //绘制时间刻度，方法1
    private void timeScale1(Canvas canvas, int width, int height) {
        //内圈斜边
        int innerC = (int) (width /2*0.9f);
        for (int i = 0; i < 12; i++) {
            //得到每个时间刻度的弧度
            double th =i*Math.PI * 2 / 12;
            //求内圈x,y
            //求邻边，cos(th)*斜边
            int innerB = (int) (innerC * Math.cos(th));
            int y = height /2 - innerB;
            //求对边，sin(th)*斜边
            int innerA = (int) (innerC * Math.sin(th));
            int x = width /2 + innerA;
            //求外圈x,y
            int outB = (int) (width /2 * Math.cos(th));
            int outBy = height /2 - outB;
            int outA = (int) (width /2 * Math.sin(th));
            int outAx = width /2 + outA;
            //绘制刻度
            canvas.drawLine(x, y, outAx , outBy, mScalePaint);
        }
    }
}
